#include "lcd.h"
#include "i2c.h"

// LCD地址定义
uint8_t LCD_ADDR = 0x78; // 默认地址

// LCD命令定义
#define LCD_CLEAR_DISPLAY   0x01
#define LCD_RETURN_HOME     0x02
#define LCD_ENTRY_MODE_SET  0x04
#define LCD_DISPLAY_CONTROL 0x08
#define LCD_CURSOR_SHIFT    0x10
#define LCD_FUNCTION_SET    0x20
#define LCD_SET_CGRAM_ADDR  0x40
#define LCD_SET_DDRAM_ADDR  0x80

// LCD显示控制
#define LCD_DISPLAY_ON  0x04
#define LCD_DISPLAY_OFF 0x00
#define LCD_CURSOR_ON   0x02
#define LCD_CURSOR_OFF  0x00
#define LCD_BLINK_ON    0x01
#define LCD_BLINK_OFF   0x00

// LCD功能设置
#define LCD_8BIT_MODE  0x10
#define LCD_4BIT_MODE  0x00
#define LCD_2LINE      0x08
#define LCD_1LINE      0x00
#define LCD_5x10DOTS   0x04
#define LCD_5x8DOTS    0x00

// LCD行地址
#define LCD_LINE1 0x00
#define LCD_LINE2 0x40

// 背光控制
#define LCD_BACKLIGHT_ON  0x08
#define LCD_BACKLIGHT_OFF 0x00

// 延时函数
static void LCD_Delay(uint32_t ms)
{
    HAL_Delay(ms);
}

// 写命令
void LCD_WriteCmd(uint8_t cmd)
{
    uint8_t data[4];
    data[0] = (cmd & 0xF0) | 0x04 | LCD_BACKLIGHT_ON;  // 高4位 + RS=0, RW=0, E=1, 背光开
    data[1] = (cmd & 0xF0) | 0x00 | LCD_BACKLIGHT_ON;  // 高4位 + RS=0, RW=0, E=0, 背光开
    data[2] = ((cmd << 4) & 0xF0) | 0x04 | LCD_BACKLIGHT_ON;  // 低4位 + RS=0, RW=0, E=1, 背光开
    data[3] = ((cmd << 4) & 0xF0) | 0x00 | LCD_BACKLIGHT_ON;  // 低4位 + RS=0, RW=0, E=0, 背光开
    
    HAL_I2C_Master_Transmit(&hi2c1, LCD_ADDR << 1, data, 4, 100);
    LCD_Delay(1);
}

// 写数据
void LCD_WriteData(uint8_t data)
{
    uint8_t buf[4];
    buf[0] = (data & 0xF0) | 0x05 | LCD_BACKLIGHT_ON;  // 高4位 + RS=1, RW=0, E=1, 背光开
    buf[1] = (data & 0xF0) | 0x01 | LCD_BACKLIGHT_ON;  // 高4位 + RS=1, RW=0, E=0, 背光开
    buf[2] = ((data << 4) & 0xF0) | 0x05 | LCD_BACKLIGHT_ON;  // 低4位 + RS=1, RW=0, E=1, 背光开
    buf[3] = ((data << 4) & 0xF0) | 0x01 | LCD_BACKLIGHT_ON;  // 低4位 + RS=1, RW=0, E=0, 背光开
    
    HAL_I2C_Master_Transmit(&hi2c1, LCD_ADDR << 1, buf, 4, 100);
    LCD_Delay(1);
}

// 初始化LCD
void LCD_Init(void)
{
    uint8_t test_addr = 0;
    HAL_StatusTypeDef status;
    
    // 尝试不同的I2C地址
    for(test_addr = 0x20; test_addr < 0x28; test_addr++)
    {
        status = HAL_I2C_IsDeviceReady(&hi2c1, test_addr << 1, 1, 100);
        if(status == HAL_OK)
        {
            // 找到设备，更新地址
            LCD_ADDR = test_addr;
            break;
        }
    }
    
    LCD_Delay(50);  // 等待LCD稳定
    
    // 初始化LCD
    LCD_WriteCmd(0x33);  // 初始化
    LCD_WriteCmd(0x32);  // 初始化
    LCD_WriteCmd(0x28);  // 4位模式，2行显示，5x8点阵
    LCD_WriteCmd(0x0C);  // 显示开，光标关，闪烁关
    LCD_WriteCmd(0x06);  // 文字不动，地址自动+1
    LCD_WriteCmd(0x01);  // 清屏
    LCD_Delay(2);
}

// 清屏
void LCD_Clear(void)
{
    LCD_WriteCmd(LCD_CLEAR_DISPLAY);
    LCD_Delay(2);
}

// 显示字符串
void LCD_ShowString(uint8_t x, uint8_t y, const char *str)
{
    uint8_t addr;
    
    // 设置显示位置
    if(y == 0)
        addr = LCD_LINE1 + x;
    else
        addr = LCD_LINE2 + x;
    
    LCD_WriteCmd(LCD_SET_DDRAM_ADDR | addr);
    
    // 显示字符串
    while(*str)
    {
        LCD_WriteData(*str++);
    }
} 